package com.ashlikun.core.activity

import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import androidx.activity.result.ActivityResult
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import com.ashlikun.core.BaseUtils
import com.ashlikun.core.listener.IBaseWindow
import com.ashlikun.core.listener.OnDispatcherMessage
import com.ashlikun.okhttputils.http.OkHttpManage
import com.ashlikun.utils.bug.BugUtils
import kotlin.math.abs

/**
 * 作者　　: 李坤
 * 创建时间: 2024/9/6　13:31
 * 邮箱　　：496546144@qq.com
 *
 * 功能介绍：把BaseActivity再抽离，去除耦合的其他库
 */
open abstract class IBaseActivity : AppCompatActivity(), IBaseWindow, OnDispatcherMessage {
    private val activityResultCalls: MutableMap<Int, (ActivityResult) -> Unit> by lazy {
        mutableMapOf()
    }

    open val thisMy by lazy {
        this
    }

    /**
     * 当调用Activity的getResources将被调用，便于hook,只调用一次，内部会缓存
     */
    protected open val myResources: Resources by lazy {
        var result = super.getResources()
        BaseUtils.activityGetResources?.forEach {
            result = it(result)
        }
        result
    }

    //与Fragment方法统一 Context
    override val requireContext: Context
        get() = this

    //与Fragment方法统一  activity
    open val requireActivity: IBaseActivity
        get() = this

    //请求CODE
    open val REQUEST_CODE by lazy {
        abs(this.javaClass.simpleName.hashCode() % 60000)
    }


    override fun getResources(): Resources {
        return myResources
    }

    var baseContextIsChang = false
    override fun applyOverrideConfiguration(overrideConfiguration: Configuration) {
        var newConfiguration = overrideConfiguration
        BaseUtils.applyOverrideConfiguration?.forEach {
            newConfiguration = it(newConfiguration)
        }
        super.applyOverrideConfiguration(newConfiguration)
    }


    override fun attachBaseContext(newBase: Context) {
        var newContext = newBase
        BaseUtils.attachBaseContext?.forEach {
            newContext = it(newContext)
            baseContextIsChang = newContext != newBase
        }
        super.attachBaseContext(newContext)

    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        var newConfiguration = newConfig
        BaseUtils.configurationChanged?.forEach {
            newConfiguration = it(newConfiguration)
        }
        super.onConfigurationChanged(newConfiguration)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        BaseUtils.activityPreCreated?.forEach {
            it(this, savedInstanceState)
        }
        BugUtils.orientationBug8_0(this)
        super.onCreate(savedInstanceState)
        if (intent == null) {
            intent = Intent()
        }
        parseIntent(intent)
        setActivityContentView()
        setSafeArea()
        baseInitView()
        initView()
        initData()
    }

    override fun onNewIntent(intent: Intent) {
        var intent: Intent? = intent
        super.onNewIntent(intent)
        if (intent == null) {
            intent = Intent()
        }
        setIntent(intent)
        parseIntent(intent)
        newData()
    }

    /**
     * 设置 安全区
     */
    protected open fun setSafeArea() {
        BaseUtils.onSetSafeArea(this)
    }

    /**
     * 设置activity的布局，可以重写
     */
    protected open fun setActivityContentView() {
        val layoutId = layoutId
        if (layoutId != View.NO_ID) {
            setContentView(layoutId)
        } else {
            var view: View? = contentView
            if (view != null) {
                setContentView(view)
            } else {
                view = binding?.root
                view?.let { setContentView(it) }
            }
        }
    }

    /**
     * 基本的View初始化
     */
    protected open fun baseInitView() {
    }

    override fun <T : View?> f(@IdRes id: Int): T? {
        return findViewById(id)
    }


    /**
     * onNewIntent 触发的调用
     */
    protected open fun newData() {}

    /**
     * ：解析意图
     */
    protected open fun parseIntent(intent: Intent) {

    }

    override fun onResume() {
        super.onResume()
    }

    override fun onStart() {
        super.onStart()
    }

    override fun onPause() {
        super.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        cancelAllHttp()
        activityResultCalls.clear()
    }


    override fun onLowMemory() {
        super.onLowMemory()
        cancelAllHttp()
        activityResultCalls.clear()
    }

    override fun finish() {
        super.finish()
    }

    /**
     * 销毁网络访问
     */
    override fun cancelAllHttp() {
        OkHttpManage.cancelTag(this)
    }

    /**
     * 处理fragment发送过来的事件
     *
     * @param what:事件类型
     * @param bundle    事件传递的数据
     */
    override fun onDispatcherMessage(what: Int, bundle: Bundle) {}

    /**
     * 处理fragment发送过来的数据
     *
     * @param what:事件类型
     * @param data      事件传递的数据
     */
    override fun onDispatcherMessage(what: Int, data: Any) {}

    /**
     * 提供数据给Fragment
     *
     * @param what:事件类型
     * @return 事件传递的数据
     */
    override fun <T> getDispatcherMessage(what: Int): T? {
        return null
    }

    open fun getUserVisibleHint(): Boolean {
        return true
    }


    fun registerResultCall(requestCode: Int, call: (ActivityResult) -> Unit) {
        activityResultCalls[requestCode] = call
    }

    fun unRegisterResultCall(requestCode: Int) {
        activityResultCalls.remove(requestCode)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        activityResultCalls[requestCode]?.invoke(ActivityResult(requestCode, data))
    }

    override fun onUserInteraction() {
        super.onUserInteraction()
        BaseUtils.userInteraction?.forEach {
            it(this)
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        BaseUtils.dispatchTouchEvent?.forEach {
            if (it(this, ev)) return true
        }
        return super.dispatchTouchEvent(ev)
    }
}